#pragma once

#include <memory>
#include <stack>
#include "Containers/Containers.h"
#include "ScriptCompiler/Description/DecoratedTypeDescription.h"
#include "ScriptCompiler/SemanticAnalyzer/StatementType.h"

class CScriptFileContext;
class CFunctionBodyDescription;
class CParameterDescription;
class IFrameOperation;
class CVariableDescription;
class CStatementContext;
class CGSharpFieldDescription;
class CTypeDescription;

class CFunctionContext : public std::enable_shared_from_this<CFunctionContext>
{
public:
    CFunctionContext(std::shared_ptr<CFunctionBodyDescription> InFunctionBody
        ,const SDecoratedTypeDescription &InReturnType
        ,const TVector<std::shared_ptr<CParameterDescription>> & InParameters
        ,std::shared_ptr<CScriptFileContext> InFileContext 
        ,std::shared_ptr<CTypeDescription> InOwnerClass
        );

    //create a new sentence context
    //ParentSentence: the parent sentence context of the new sentence, can be NULL
    std::shared_ptr<CStatementContext> NewSentence(
        std::shared_ptr<CStatementContext> ParentSentence
        ,EStatementType InStatementType
        );

    // std::shared_ptr<CNameSearchTreeNode> NameDirectory;
    std::weak_ptr<CTypeDescription> OwnerClass;

    SDecoratedTypeDescription ReturnType;

    std::shared_ptr<CScriptFileContext> FileContext;

    std::shared_ptr<CFunctionBodyDescription> FunctionBody;

    TVector<std::shared_ptr<CParameterDescription>>  Parameters;

    bool bIsStatic=false;

    std::shared_ptr<CParameterDescription> FindParameterByName(const CString& InParameterName);

    std::shared_ptr<CTypeDescription> GetOwnerClass();

    //jump target of break statement in loop
    std::stack<std::shared_ptr<IFrameOperation>> BreakJumpTargets;

    //jump target of continue statement in loop
    std::stack<std::shared_ptr<IFrameOperation>> LoopContinueJumpTargets;
};